package com.cskaoyan.javase.oop1._5this;

import java.io.PushbackInputStream;

/**
 * this关键字
 * 学习完对象与类后，做以下练习：
 * 创建一个汽车类
 * 有颜色（color）和速度（speed）两个属性，行为是可以跑（run）。
 *
 * 实现：
 *      1.在run成员方法中访问速度和颜色两个属性，调用该方法查看结果。
 *      2.在run成员方法的形参列表中，添加一个局部变量speed，不修改方法体，调用该方法查看结果。
 *
 * 当形参变量的名字和同类下的成员变量名同名,且在方法内部要访问这个同名变量时
 * 会根据"就近原则" 优先匹配形参的局部变量
 * 这时方法给出的结果,就是形参局部变量的结果
 *
 * 在以上场景下, 如何去访问同类中的同名成员变量呢?
 * 在这种场景下,就需要使用"this"关键字
 *
 * this关键字是什么?
 * 在任何一个Java类中,成员方法的形参列表中,总是隐含了一个this传参
 * 表示传入当前对象
 * 也就是说this指向当前对象,this关键字实际上是一个引用
 * 这个引用叫this,它指向当前对象
 *
 * 什么是当前对象?
 * 成员方法总是需要一个对象来调用它(对象名.调用)
 * 所以谁来调用这个成员方法,谁就是当前对象
 *
 * this关键字的用途:
 *      1.它是类中成员方法的隐含传参,它指向当前对象
 *          所以this.可以用于在成员方法中,访问同类中的成员变量和成员方法
 *          这也就是为什么成员方法可以无条件的直接访问同类的成员
 *          原因是成员方法中已经存在this,指向当前对象了.
 *
 *      2.this是一个隐含传参,如无必要,没有要写出"this."访问成员,它是隐含的
 *          但是有一种情况例外:
 *          当成员变量和形参同名时,就必须写出"this."以示区分
 *          否则访问的就是同名的形参局部变量(就近原则)
 *
 *      3.(重点)static方法中是不存在this传参的,所以static方法中是不能直接访问同类下成员的
 *          但是不能直接访问
 *          不是不能访问
 *          现在static方法中没有对象,所以不能访问成员
 *          想访问,那就自己new一个对象,照样可以访问
 *
 *     4.未完待续...
 *
 * @since 10:53
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Car c = new Car();
        c.color = "黑色";
        c.speed = 120;
        // c.run();
        // 在这一次方法调用过程中,c就是当前对象,在run方法中形参列表中隐含的this传参,就指向c对象
        c.run(180);
        System.out.println(c);

        System.out.println("---------------------");
        Car c2 = new Car();
        c2.speed = 100;
        // 对于这次方法调用来说,this指向c2对象
        c2.run(200);
        System.out.println(c2);
    }
}

class Car {
    String color;
    double speed;

    public void run(double speed) {
        // this是一个引用,它可以直接输出
        System.out.println(this);
        System.out.println(color + "小汽车嘟嘟嘟的在高速公路上,以" + this.speed + "千米每小时的速度行驶!");
    }

    public void test() {
        // 成员方法之间,在同类下,可以随意的互相调用
        test2();
    }

    public void test2() {
    }

    public static void testStatic() {
        // System.out.println(color);
        Car c = new Car();
        System.out.println(c.color);
    }
}